package com.wiscamp.ninechapters.panels.infrastructure.repositories;


import com.wiscamp.ninechapters.panels.domain.entities.Dictionary;
import com.wiscamp.ninechapters.panels.domain.repositories.DictionaryRepository;
import com.wiscamp.ninechapters.panels.infrastructure.converters.DictionaryConverter;
import com.wiscamp.ninechapters.panels.infrastructure.mappers.DictionaryMapper;
import com.wiscamp.ninechapters.panels.infrastructure.mappers.DictionaryViewMapper;
import com.wiscamp.ninechapters.panels.infrastructure.po.DictionaryPO;
import com.wiscamp.ninechapters.panels.infrastructure.views.DictionaryView;
import cube.ddd.aspect.HandleDataException;
import cube.ddd.common.query.PagedObjects;
import cube.ddd.common.query.PagedQuery;
import cube.ddd.utils.PersistenceUtils;
import org.springframework.stereotype.Repository;

import java.util.Collection;

@Repository
public class DictionaryRepositoryImpl implements DictionaryRepository {

    private final DictionaryMapper dictionaryMapper;

    private final DictionaryViewMapper dictionaryViewMapper;

    public DictionaryRepositoryImpl(DictionaryMapper dictionaryMapper, DictionaryViewMapper dictionaryViewMapper) {
        this.dictionaryMapper = dictionaryMapper;
        this.dictionaryViewMapper = dictionaryViewMapper;
    }

    private DictionaryPO getDictionaryPO(long dictionaryId) {
        return PersistenceUtils.findById(dictionaryId, dictionaryMapper::findById);
    }

    @HandleDataException
    public Dictionary getDictionary(long dictionaryId) {
        return PersistenceUtils.findEntityById(dictionaryId, dictionaryViewMapper::findById,
                DictionaryConverter.Instance::toDictionaryByView);
    }

    @HandleDataException
    public Dictionary getDictionaryByCode(long appId, String dictionaryCode) {
        return PersistenceUtils.getEntityByIdAndText(appId, dictionaryCode, dictionaryViewMapper::findByDictionaryCode,
                DictionaryConverter.Instance::toDictionaryByView);
    }

    @HandleDataException
    public Collection<Dictionary> getDictionariesByIds(Collection<Long> dictionaryIds) {
        return PersistenceUtils.getEntitiesByIds(dictionaryIds, dictionaryViewMapper::findAllById,
                DictionaryConverter.Instance::toDictionaryByView);
    }

    @HandleDataException
    public Collection<Dictionary> getDictionariesByGroup(long appId, String dictionaryGroup) {
        return PersistenceUtils.getEntitiesByIdAndText(appId, dictionaryGroup, dictionaryViewMapper::findListByDictionaryGroup,
                DictionaryConverter.Instance::toDictionaryByView);
    }

    @HandleDataException
    public Collection<Dictionary> getDictionariesByName(long appId, String dictionaryName) {
        return PersistenceUtils.getEntitiesByIdAndText(appId, dictionaryName, dictionaryViewMapper::findListByDictionaryName,
                DictionaryConverter.Instance::toDictionaryByView);
    }

    @HandleDataException
    public PagedObjects<Dictionary> getDictionariesByQuery(PagedQuery query) {
        PagedObjects<DictionaryView> pagedObjects = PersistenceUtils.getPersistenceObjectsByQuery(query, dictionaryViewMapper::findAll);
        return PersistenceUtils.convertPagedObjects(pagedObjects, DictionaryConverter.Instance::toDictionaryByView);
    }

    @HandleDataException
    public Dictionary saveDictionary(Dictionary dictionary) {
        if (dictionary.getDictionaryId() <= 0) {
            return PersistenceUtils.createEntity(dictionary, dictionaryMapper::saveAndFlush,
                    DictionaryConverter.Instance::toDictionaryPO, DictionaryConverter.Instance::toDictionary);
        } else {
            var existedPO = getDictionaryPO(dictionary.getDictionaryId());
            if (existedPO == null) existedPO = new DictionaryPO();
            return PersistenceUtils.updateEntity(dictionary, existedPO, dictionaryMapper::saveAndFlush,
                    DictionaryConverter.Instance::toDictionaryPO, DictionaryConverter.Instance::toDictionary);
        }
    }
}
